package aleksandar.djuric.gui;

import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Toolkit;

import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import java.awt.Point;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JFrame;
import javax.swing.JDialog;
import javax.swing.JScrollPane;



import java.awt.FlowLayout;
import java.net.URI;
import java.net.URL;
import java.util.LinkedList;

import javax.swing.JTree;
import javax.swing.JSplitPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.JPopupMenu;

import aleksandar.djuric.common.TimeManagement;
import aleksandar.djuric.entities.Player;
import aleksandar.djuric.entities.Team;
import aleksandar.djuric.offline.EncodedFileReadWrite;
import aleksandar.djuric.offline.OfflineDataManager;
import aleksandar.djuric.online.FIDataFetcher;
import aleksandar.djuric.statistics.Statistics;


public class MainFrame implements ActionListener, ComponentListener, 
								TreeSelectionListener, MouseListener,
								HyperlinkListener
{

	private JFrame jFrame = null;
	private JPanel jContentPane = null;
	private JMenuBar jJMenuBar = null;
	private JMenu gameMenu = null;
	private JMenu helpMenu = null;
	private JMenuItem exitMenuItem = null;
	private JMenuItem aboutMenuItem = null;
	private JMenuItem helpMenuItem = null;
	private JMenuItem fidMenuItem = null;
	private JDialog aboutDialog = null;
	private JPanel aboutContentPane = null;
	private JLabel aboutVersionLabel = null;
	private JMenuItem jMenuItem = null;  //  @jve:decl-index=0:visual-constraint="192,280"
	private JMenuItem onlineMenuItem = null;
	private JScrollPane jScrollPane1 = null;
	private JTree jTree = null;
	private JSplitPane jSplitPane = null;
	private ColorPane display = null;
	private LinkedList<Team> teams = null;  //  @jve:decl-index=0:
	private JScrollPane jScrollPane = null;
	private ToolTip trainToolTip = null;
	
	public static MainFrame mainFrame = null;
	
	private FIDataFetcher fetcher = null;  //  @jve:decl-index=0:
	private JPopupMenu jPopupMenu = null;  //  @jve:decl-index=0:visual-constraint="739,196"
	
	private String[] userPass = null;
	public Image[] waiters = null;
	private Waiter waiter = null;
	private ImageIcon refresh = null;
	private ImageIcon offline = null;
	private ImageIcon online = null;
	private ImageIcon offlineOnline = null;
	private Image icon = null;
	private URL[] trainingUrls = null;
	
//	private JMenu sortMenu = null;
//	private JRadioButtonMenuItem jRadioButtonMenuItem = null;
//	private JRadioButtonMenuItem jRadioButtonMenuItem1 = null;
	private LeafCellRenderer leafRenderer = null;
	private JMenuItem statsMenuItem = null;
	private JMenuItem test = null;
	private Statistics stats = null;
	public MainFrame()
	{
		mainFrame = this;
		waiters = new Image[12];
		URL url = null;
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for (int i = 1; i < 13; i++) {
			url = this.getClass().getResource("/waiter/" + i + ".png");
			waiters[i - 1] = toolkit.getImage(url);
		}
		url = this.getClass().getResource("/images/refresh.png");
		refresh = new ImageIcon(url);
		url = this.getClass().getResource("/images/icon.jpg");
		icon = toolkit.getImage(url);
		url = this.getClass().getResource("/images/offline.gif");
		offline = new ImageIcon(url);
		url = this.getClass().getResource("/images/online.gif");
		online = new ImageIcon(url);
		leafRenderer = new LeafCellRenderer(offline, online);
		url = this.getClass().getResource("/images/offlineOnline.gif");
		offlineOnline = new ImageIcon(url);
		trainingUrls = new URL[5];
		for (int i = 0; i < 5; i++) {
			trainingUrls[i] = this.getClass().getResource(
					"/trainingGifs/train" +
					i +
					".gif");
		}
		
	}
	
	public FIDataFetcher getFetcher()
	{
		if(fetcher == null)
		{
			if(userPass == null)
				userPass = EncodedFileReadWrite.read();
			if(userPass == null)
			{
				boolean isEnabled = getJFrame().isEnabled();
				UserPassPanel panel = new UserPassPanel();
				int answer = JOptionPane.showConfirmDialog(
						getJFrame(), panel, "Login to Football Identity.",
						JOptionPane.OK_CANCEL_OPTION,
						JOptionPane.PLAIN_MESSAGE);
				getJFrame().setEnabled(true);
				getJFrame().requestFocus();
				if(!isEnabled)
					getJFrame().setEnabled(false);
				if (answer == JOptionPane.OK_OPTION)
				{
					fetcher = new FIDataFetcher(
							panel.getJTextField().getText(),
							new String (
									panel.getJPasswordField().getPassword()));
					int response = fetcher.login();
					if(response == 0)
					{
						userPass = new String[2];
						userPass[0] = panel.getJTextField().getText();
						userPass[1] = new String(
									panel.getJPasswordField().getPassword());
						if(panel.getJCheckBox().isSelected())
						{
							EncodedFileReadWrite.write(
									panel.getJTextField().getText(),
									String.valueOf(
										panel.getJPasswordField().getPassword()));
						}
					}
					else if(response == 1)
					{
						fetcher = null;
						getDisplay().setText(Color.RED,
								"Incorect username or password.");
					}
					else
					{
						fetcher = null;
						getDisplay().setText(Color.RED,
									"Error, could not connect to server.");
					}
				}
				else
				{
					getDisplay().setText("Operation aborted by user.");
				}
			}
			else
			{
				fetcher = new FIDataFetcher(userPass[0], userPass[1]);
				int response = fetcher.login();
				if(response == 1)
				{
					fetcher = null;
					getDisplay().setText(Color.RED,
							"Incorect username or password.");
					EncodedFileReadWrite.deleteIni();
					userPass = null;
				}
				else if(!(response == 0))
				{
					fetcher = null;
					getDisplay().setText(Color.RED,
								"Error, could not connect to server (" +
								response + 
								").");
				}
			}
		}
		return fetcher;
	}
	
	private class League
	{
		private String name = "Right click me!";
		
		@Override
		public String toString() {
			return name;
		}
	}
	
	public DefaultMutableTreeNode createTree()
	{
		League l = new League();
		DefaultMutableTreeNode root = 
			new DefaultMutableTreeNode(l);
		DefaultMutableTreeNode tmp = null;
		if(teams == null)
			teams = OfflineDataManager.load(getDisplay());
		if(teams != null)
		{
			Team team = null;
			for (int i = 0; i < teams.size(); i++) {
				team = teams.get(i);
				tmp = new DefaultMutableTreeNode(team);
				root.add(tmp);
				for (int j = 0; j < team.getNPlayers(); j++)
				{
					DefaultMutableTreeNode node = 
						new DefaultMutableTreeNode(team.getPlayer(j));
					tmp.add(node);
				}
			}
		}
		if(OfflineDataManager.getMyleague() != null)
			l.name = " " + OfflineDataManager.getMyleague();
		else if(fetcher != null)
			if(getFetcher().getMyLeague() != null)
				l.name = " " + getFetcher().getMyLeague();
		return root;
	}
	
	/**
	 * This method initializes jFrame
	 * 
	 * @return javax.swing.JFrame
	 */
	public JFrame getJFrame() {
		if (jFrame == null) {
			jFrame = new JFrame();
			jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			jFrame.setJMenuBar(getJJMenuBar());
			jFrame.setSize(600, 800);
			jFrame.setLocation(500, 100);
			jFrame.setContentPane(getJContentPane());
			jFrame.setTitle("Football Identity data fetcher");
			jFrame.setIconImage(icon);
			jFrame.addWindowListener(new WindowAdapter() {
				@Override
				public void windowClosed(WindowEvent e) {
					exit();
				}
			});
		}
		return jFrame;
	}
	
	public void exit()
	{
		if(fetcher != null)
			fetcher.shutDownConnection();
		System.exit(0);
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJSplitPane(), BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJJMenuBar() {
		if (jJMenuBar == null) {
			jJMenuBar = new JMenuBar();
			jJMenuBar.setLayout(
					new FlowLayout(FlowLayout.LEADING, 0, 0));
			jJMenuBar.add(getGameMenu());
			jJMenuBar.add(getHelpMenu());
//			jJMenuBar.add(getJMenu());
			
		}
		return jJMenuBar;
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getGameMenu() {
		if (gameMenu == null) {
			gameMenu = new JMenu();
			gameMenu.setText("Game");
//			gameMenu.add(getTest());
			gameMenu.add(getFidMenuItem());
			gameMenu.add(getStatsMenuItem());
			gameMenu.addSeparator();
			gameMenu.add(getExitMenuItem());
		}
		return gameMenu;
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getHelpMenu() {
		if (helpMenu == null) {
			helpMenu = new JMenu();
			helpMenu.setText("Help");
			helpMenu.add(getHelpMenuItem());
			helpMenu.add(getAboutMenuItem());
		}
		return helpMenu;
	}
	
	private JMenuItem getFidMenuItem()
	{
		if(fidMenuItem == null)
		{
			fidMenuItem = new JMenuItem();
			fidMenuItem.setText("FID Home Page");
			fidMenuItem.addActionListener(this);
		}
		return fidMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getExitMenuItem() {
		if (exitMenuItem == null) {
			exitMenuItem = new JMenuItem();
			exitMenuItem.setText("Exit");
			exitMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					getJFrame().dispose();
				}
			});
		}
		return exitMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getAboutMenuItem() {
		if (aboutMenuItem == null) {
			aboutMenuItem = new JMenuItem();
			aboutMenuItem.setText("About");
			aboutMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JDialog aboutDialog = getAboutDialog();
					aboutDialog.setSize(300,200);
					Point loc = getJFrame().getLocation();
					loc.translate(200, 100);
					aboutDialog.setLocation(loc);
					aboutDialog.setVisible(true);
				}
			});
		}
		return aboutMenuItem;
	}

	/**
	 * This method initializes aboutDialog	
	 * 	
	 * @return javax.swing.JDialog
	 */
	private JDialog getAboutDialog() {
		if (aboutDialog == null) {
			aboutDialog = new JDialog(getJFrame(), true);
			aboutDialog.setTitle("About");
			aboutDialog.setContentPane(getAboutContentPane());
		}
		return aboutDialog;
	}

	/**
	 * This method initializes aboutContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getAboutContentPane() {
		if (aboutContentPane == null) {
			aboutContentPane = new JPanel();
			aboutContentPane.setLayout(new BorderLayout());
			aboutContentPane.add(getAboutVersionLabel(), BorderLayout.CENTER);
		}
		return aboutContentPane;
	}

	/**
	 * This method initializes aboutVersionLabel	
	 * 	
	 * @return javax.swing.JLabel	
	 */
	private JLabel getAboutVersionLabel() {
		if (aboutVersionLabel == null) {
			aboutVersionLabel = new JLabel();
			aboutVersionLabel.setText("<html><P align=\"center\">" +
					"<br>FID data fetcher<br>" +
					"Program that downloads and displays teams<br>" +
					"\tand players from the online game Football Identity.<br>" +
					"<br>Version 2.9.1<br><br>" +
					"Copyright Aleksandar Đurić<br>" +
					"2011-2013<br> </p></html>");
			aboutVersionLabel.setHorizontalAlignment(SwingConstants.CENTER);
		}
		return aboutVersionLabel;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getHelpMenuItem() {
		if (helpMenuItem == null) {
			helpMenuItem = new JMenuItem();
			helpMenuItem.setText("Help");
			helpMenuItem.addActionListener(this);
		}
		return helpMenuItem;
	}
	
	public void showHelp()
	{
		getDisplay().setText(
				"<b>" +
				"To get the data from the Internet<br>" +
				"right click on the item that you want to download<br>" +
				"and select \"refresh\" from the drop-down menu.<br><br>" +
				"To get an item information just click on it.<br><br>" +
				"To expand an item double click it.<br><br>" +
				"To perform training go to your character screen<br>" +
				"and click on the value of the attribute u want to train.<br><br>" +
				"The Power is sum of all attribute values.<br><br>" +
				"The Power51 is sum of all points spent over 51 attribute value.<br><br>" +
				"If the name of the player is red, it means that he has no user.<br>" +
				"If the name is orange, he didn't log on for more then 7 days.<br>" +
				"If the name is yellow, he didn't log on during the previous day.</b>"
				);
	}

	/**
	 * This method initializes ColorPane	
	 * 	
	 * @return ColorPane	
	 */
	public ColorPane getDisplay() {
		if (display == null) {
			display = new ColorPane();
			display.setEditable(false);
			display.setFont(
					new Font(display.getFont().getName(),
							Font.BOLD,
							display.getFont().getSize()));
			display.addMouseListener(this);
			display.addHyperlinkListener(this);
			showHelp();
//			display.setBackground(Color.LIGHT_GRAY);
//			for (int i = 0; i < 256; i+=23) {
//				display.append(new Color(i, 255 - i, 0), "M");
//				System.out.println(i);
//			}
//			display.setEditable(true);
//			display.replaceSelection("djura");
		}
		return display;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getJMenuItem() {
		if (jMenuItem == null) {
			jMenuItem = new JMenuItem();
			jMenuItem.setText("Refresh");
			jMenuItem.setIcon(refresh);
			jMenuItem.addActionListener(this);
		}
		return jMenuItem;
	}
	
	private JMenuItem getOnlineMenuItem()
	{
		if (onlineMenuItem == null)
		{
			onlineMenuItem = new JMenuItem();
			onlineMenuItem.setText("Players online");
			onlineMenuItem.setIcon(offlineOnline);
			onlineMenuItem.setVisible(false);
			onlineMenuItem.addActionListener(this);
		}
		return onlineMenuItem;
	}

	/**
	 * This method initializes jScrollPane1	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane1() {
		if (jScrollPane1 == null) {
			jScrollPane1 = new JScrollPane();
			jScrollPane1.setViewportView(getJTree());
			jScrollPane1.setMinimumSize(jScrollPane1.getSize());
		}
		return jScrollPane1;
	}

	/**
	 * This method initializes jTree	
	 * 	
	 * @return javax.swing.JTree	
	 */
	public JTree getJTree() {
		if (jTree == null) {
			jTree = new JTree(createTree());
			jTree.addComponentListener(this);
			jTree.addTreeSelectionListener(this);
			jTree.addMouseListener(this);
			jTree.setFont(
					new Font(jTree.getFont().getName(),
							Font.BOLD,
							jTree.getFont().getSize()));
			jTree.setCellRenderer(leafRenderer);
//			jTree.putClientProperty("JTree.lineStyle", "None");
		}
		return jTree;
	}

	/**
	 * This method initializes jSplitPane	
	 * 	
	 * @return javax.swing.JSplitPane	
	 */
	private JSplitPane getJSplitPane() {
		if (jSplitPane == null) {
			jSplitPane = new JSplitPane();
			jSplitPane.setLeftComponent(getJScrollPane1());
			jSplitPane.setRightComponent(getJScrollPane());
			jSplitPane.addComponentListener(this);
			jSplitPane.setDividerSize(3);
		}
		return jSplitPane;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getDisplay());
		}
		return jScrollPane;
	}
	
	public void scrollToTheBegining()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				getJScrollPane().getVerticalScrollBar().setValue(0);
			}
		});
		
	}

	/**
	 * This method initializes jPopupMenu	
	 * 	
	 * @return javax.swing.JPopupMenu	
	 */
	private JPopupMenu getJPopupMenu() {
		if (jPopupMenu == null) {
			jPopupMenu = new JPopupMenu();
			jPopupMenu.add(getJMenuItem());
			jPopupMenu.add(getOnlineMenuItem());
			jPopupMenu.addMouseListener(this);
		}
		return jPopupMenu;
	}
	
	private ToolTip getTrainToolTip(){
		if(trainToolTip == null)
			trainToolTip = new ToolTip(getJFrame());
		return trainToolTip;
	}
	
	private Waiter getWaiter()
	{
		if(waiter == null)
		{
			waiter = new Waiter(getJFrame());
		}
		return waiter;
	}
	
	private class PlayerFetcher extends Thread
	{
		private Player p;
		
		public PlayerFetcher(Player p)
		{
			this.p = p;
		}
		
		@Override
		public void run() {
			getFetcher().getPlayer(p);
			getDisplay().append(null, 
					p.getName() + "\n");
		}
	}
	
	private class PlayerRefresher extends Thread
	{
		private Player p;
		private Team t;
		
		public PlayerRefresher(Player p, Team t)
		{
			this.p = p;
			this.t = t;
		}
		
		@Override
		public void run() {
			getJFrame().setEnabled(false);
			getWaiter().setVisible(true);
			try
			{
				getDisplay().setText("Refreshing player " + p.getName());
				boolean isFine = getFetcher().getPlayer(p);
				if(!isFine)
				{
					fetcher = null;
					isFine = getFetcher().getPlayer(p);
				}
				if(isFine)
				{
					OfflineDataManager.write(t);
					TreePath path = getJTree().getSelectionPath();
					getJTree().clearSelection();
					getJTree().setSelectionPath(path);
				}
				else
				{
					getDisplay().append(Color.RED, "Error refreshing player "
										+ p.getName());
				}
			}
			catch(Exception e)
			{
			}
			finally
			{
				getWaiter().setVisible(false);
				getJFrame().setEnabled(true);
				
			}
			
		}
	}
	
	private void refresh(Player p, Team t)
	{
		PlayerRefresher pr = new PlayerRefresher(p,t);
		pr.start();
	}
	
	private class TeamRefresher extends Thread
	{
		private Team t;
		private boolean checkOnline;
		
		public TeamRefresher(Team t, boolean checkOnline)
		{
			this.t = t;
			this.checkOnline = checkOnline;
		}
		
		@Override
		public void run() {
			getJFrame().setEnabled(false);
			getWaiter().setVisible(true);
			try
			{
				if(checkOnline == true)
					getDisplay().setText("Refreshing online status of " +
							t.getName() +
							" players.");
				else	
					getDisplay().setText("Refreshing players data from " 
									+ t.getName()
									+ ".");
				getFetcher().login();
				if(checkOnline == true)
				{
					getFetcher().updateOnlineStatuses(t);
					TreePath path = getJTree().getSelectionPath();
					getJTree().collapsePath(path);
					getJTree().clearSelection();
					getJTree().setSelectionPath(path);
					getJTree().expandPath(path);
				}
				else
				{
					LinkedList<Player> players = 
						getFetcher().getPlayers(t.getId());
					if(players != null)
					{
						PlayerFetcher[] pFetchers = 
							new PlayerFetcher[players.size()];
						t.addPlayers(players);
						for (int i = 0; i < players.size(); i++) {
							pFetchers[i] = new PlayerFetcher(players.get(i));
							pFetchers[i].start();
						}
						for (int i = 0; i < pFetchers.length; i++) {
							pFetchers[i].join();
						}
					}
					TreePath path = getJTree().getSelectionPath();
					int row = getJTree().getRowCount() - 1;
				    while (row > 0) {
				      getJTree().collapseRow(row);
				      row--;
				    }
				    row = getJTree().getRowForPath(path);
					jTree = null;
					getJScrollPane1().setViewportView(getJTree());
					getJTree().setSelectionRow(row);
					getJTree().expandRow(row);
					OfflineDataManager.write(t);
				}
			}
			catch(Exception e)
			{	
			}
			finally
			{
				getWaiter().setVisible(false);
				getJFrame().setEnabled(true);
			}
		}
	}
	
	private void refresh(Team t, boolean checkOnline)
	{
		TeamRefresher tr = new TeamRefresher(t, checkOnline);
		tr.start();
	}
	
	private class LeagueRefresher extends Thread
	{		
		@Override
		public void run() {
			getJFrame().setEnabled(false);
			getWaiter().setVisible(true);
			try
			{
				getDisplay().setText("Refreshing League data.");
				teams = getFetcher().getTeams();
				if(teams == null)
					fetcher = null;
				teams = getFetcher().getTeams();
				if(teams != null)
				{
					jTree = null;
					OfflineDataManager.setMyleague(getFetcher().getMyLeague());
					OfflineDataManager.write(teams);
					getJScrollPane1().setViewportView(getJTree());
					getJTree().setSelectionRow(0);
				}
				else
				{
					getDisplay().append(Color.RED,
									"\nError refreshing League data.");
				}
			}
			catch(Exception e)
			{	
			}
			finally
			{
				getWaiter().setVisible(false);
				getJFrame().setEnabled(true);
			}
		}
	}
	
	private void refresh(League l)
	{
		LeagueRefresher lr = new LeagueRefresher();
		lr.start();
	}
	
	// Display train page.
	private class Trainer extends Thread
	{
		private int attribId;
		
		Trainer(int attribId)
		{
			this.attribId = attribId;
		}
		
		@Override
		public void run() {
			getJFrame().setEnabled(false);
			try
			{
				getDisplay().setText("<center><img src=\"" +
						trainingUrls[(int) Math.floor((Math.random() * 5))] + 
						"\"></img><br>Training...</center>");
		
				String returnValue = getFetcher().attributeTraining(attribId);
				
				TreePath playerPath = getJTree().getSelectionPath();
				TreePath teamPath = playerPath.getParentPath();
				Player p = (Player)
					((DefaultMutableTreeNode)
						playerPath.getLastPathComponent()).getUserObject();
				Team t = (Team)
					((DefaultMutableTreeNode)
					teamPath.getLastPathComponent()).getUserObject();
				getFetcher().getPlayer(p);			
				if(returnValue == null)
				{
					getDisplay().setText("");
					getDisplay().append(Color.RED, 
							"Error while performing training.");
				}
				else
				{
					TimeManagement.getTM().setNextTrainingDate(
							TimeManagement.getTM().getTime());
					
					OfflineDataManager.write(t);
					getDisplay().setText(returnValue + "<br>" +
							"Next training starts at " +
							TimeManagement.getTM().getNextTrainingTime()
							);
				}
				getJTree().setSelectionPath(null);

			}
			catch(Exception e)
			{	
				e.printStackTrace();
			}
			finally
			{
				getJFrame().setEnabled(true);
			}
		}
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
//	private JMenu getSortMenu() {
//		if (sortMenu == null) {
//			sortMenu = new JMenu();
//			sortMenu.setText("Sort by");
//			sortMenu.add(getJRadioButtonMenuItem());
//			sortMenu.add(getJRadioButtonMenuItem1());
//		}
//		return sortMenu;
//	}

	/**
	 * This method initializes jRadioButtonMenuItem	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
//	private JRadioButtonMenuItem getJRadioButtonMenuItem() {
//		if (jRadioButtonMenuItem == null) {
//			jRadioButtonMenuItem = new JRadioButtonMenuItem();
//			jRadioButtonMenuItem.setText("Age");
//			jRadioButtonMenuItem.setSelected(true);
//			jRadioButtonMenuItem.addActionListener(new ActionListener() 
//				{
//					@Override
//					public void actionPerformed(ActionEvent e) {
//						jRadioButtonMenuItem.setSelected(true);
//						jRadioButtonMenuItem1.setSelected(false);
//					}
//				}
//			);
//		}
//		return jRadioButtonMenuItem;
//	}

	/**
	 * This method initializes jRadioButtonMenuItem1	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
//	private JRadioButtonMenuItem getJRadioButtonMenuItem1() {
//		if (jRadioButtonMenuItem1 == null) {
//			jRadioButtonMenuItem1 = new JRadioButtonMenuItem();
//			jRadioButtonMenuItem1.setText("Power");
//			jRadioButtonMenuItem1.addActionListener(new ActionListener() 
//			{
//				@Override
//				public void actionPerformed(ActionEvent e) {
//					jRadioButtonMenuItem1.setSelected(true);
//					jRadioButtonMenuItem.setSelected(false);
////					LinkedList<Player> players = new LinkedList<Player>();
//					for (int i = 0; i < teams.size(); i++) {
//						for (int j = 0; j < teams.get(i).getNPlayers(); j++) 
//						{
////							players.add(teams.get(i).getPlayer(j));
//							System.out.println(teams.get(i) + "," +
//								teams.get(i).getPlayer(j).toStringStatistic());
//						}
//					}
//				}
//			}
//		);
//		}
//		return jRadioButtonMenuItem1;
//	}

	/**
	 * This method initializes jMenuItem1	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getStatsMenuItem() {
		if (statsMenuItem == null) {
			statsMenuItem = new JMenuItem();
			statsMenuItem.setText("get statistics");
			statsMenuItem.addActionListener(this);
		}
		return statsMenuItem;
	}

	/**
	 * This method initializes test	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	@SuppressWarnings("unused")
	private JMenuItem getTest() {
		if (test == null) {
			test = new JMenuItem("Team training");
			test.addActionListener(this);
		}
		return test;
	}

	/**
	 * Launches this application
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainFrame application = new MainFrame();
				application.getJFrame().setVisible(true);
			}
		});
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand().equalsIgnoreCase("Refresh"))
		{
//			System.out.println("Run.");
			Object selected = 
				((DefaultMutableTreeNode)
				getJTree().getLastSelectedPathComponent()).getUserObject();
			if(selected instanceof Player)
			{
				Player player = (Player)selected;
				selected = ((DefaultMutableTreeNode)getJTree()
						.getLastSelectedPathComponent()).getParent();
				selected = ((DefaultMutableTreeNode)selected).getUserObject();
				Team team = (Team)selected;
				refresh(player, team);
			}
			else if(selected instanceof Team)
			{
				refresh((Team)selected, false);
			}
			else
			{
				refresh((League)selected);
			}			
		}
		else if(e.getActionCommand().equalsIgnoreCase("Players online"))
		{
			Object selected = 
				((DefaultMutableTreeNode)
				getJTree().getLastSelectedPathComponent()).getUserObject();
			refresh((Team)selected, true);
		}
		else if(e.getActionCommand().equalsIgnoreCase("help"))
		{
			showHelp();
		}
		else if(e.getActionCommand().equalsIgnoreCase("FID Home Page"))
		{
			try
			{
				Desktop.getDesktop().browse(new URI("www.footballidentity.com"));
			}
			catch(Exception exc)
			{
				getDisplay().setText("" +
						"<p><font color=\"red\">" +
						"Your Java does not support this operation." +
						"</font></p");
			}
		}
		else if(e.getActionCommand().equalsIgnoreCase("get statistics"))
		{
			stats = new Statistics();
			stats.start();
			
		}
		else if(e.getActionCommand().equalsIgnoreCase("Team training"))
		{
			getDisplay().setText(getFetcher().teamTraining());
		}
	}
	
	@Override
	public void componentHidden(ComponentEvent e) {
		
	}

	@Override
	public void componentMoved(ComponentEvent e) {
		
	}

	@Override
	public void componentResized(ComponentEvent e) {
		getJScrollPane().setPreferredSize(
				new Dimension(200, 0));
		getJSplitPane().resetToPreferredSizes();
	}

	@Override
	public void componentShown(ComponentEvent e) {
		
	}

	@Override
	public void valueChanged(TreeSelectionEvent e) {
		DefaultMutableTreeNode selected = 
			(DefaultMutableTreeNode) getJTree().getLastSelectedPathComponent();
		if(selected != null)
		{
			Object o = selected.getUserObject();
			if(o instanceof Player)
				getDisplay().setText(((Player)o).toStringDisplay());
			else if (o instanceof Team)
				getDisplay().setText(((Team)o).toStringDisplay());
			else
			{
				StringBuilder s = new StringBuilder();
				DefaultMutableTreeNode root = 
					(DefaultMutableTreeNode)getJTree().getModel().getRoot();
				League l = (League)root.getUserObject();

				s.append(l.name);
				s.append("<br><br>");
				if(teams != null)
					for (int i = 0; i < teams.size(); i++) {
						s.append(" - ");
						s.append("<a href=\"" +
								i +
								"\">" + 
								 teams.get(i).getName() + 
								 "</a>");
						s.append("<br>");
					}
				getDisplay().setText(s.toString());
			}
			
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if(e.isMetaDown())
		{
			if(e.getComponent().equals(getJTree()))
			{
				int row = getJTree().getRowForLocation(
						e.getX(), e.getY());
				if(row != -1)
					getJTree().setSelectionRow(row);
				if(!getJTree().isSelectionEmpty())
				{
					DefaultMutableTreeNode node =
						(DefaultMutableTreeNode)
						getJTree().getSelectionPath().getLastPathComponent();
					if(node.getUserObject() instanceof Team && !node.isLeaf())
						getOnlineMenuItem().setVisible(true);
					else
						getOnlineMenuItem().setVisible(false);
					getJPopupMenu().show(e.getComponent(), e.getX(), e.getY());
				}
			}
			else if(e.getComponent().equals(getDisplay()))
			{
				if(getJTree().getLastSelectedPathComponent() != null)
				{
					getJPopupMenu().show(e.getComponent(), e.getX(), e.getY());
				}
			}
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		
	}

	@Override
	public void hyperlinkUpdate(HyperlinkEvent e) {
		int i = Integer.valueOf(e.getDescription());
		if(e.getEventType().equals(EventType.ACTIVATED))
		{
			if(i < Player.firstAttribID)
			{
				TreePath path = getJTree().getSelectionPath();
				
				DefaultMutableTreeNode node =
						(DefaultMutableTreeNode)
						(getJTree().getLastSelectedPathComponent());
				if(!node.isLeaf())
				{
					node = (DefaultMutableTreeNode)node.getChildAt(i);
					getJTree().setSelectionPath(path.pathByAddingChild(node));
				}
			}
			else
			{
				getTrainToolTip().setVisible(false);
				if(TimeManagement.getTM().canTrain())
				{
					int answer = JOptionPane.showConfirmDialog(
							getJFrame(),
							"Are you sure you want to perform Attribute \"" +
							Player.attribNames[i - Player.firstAttribID] +
							"\" training?",
							"Perform training?",
							JOptionPane.YES_NO_OPTION);
					if(answer == JOptionPane.YES_OPTION)
					{
						Trainer trainer = new Trainer(i);
						trainer.start();
					}
				}
				else
				{
					JOptionPane.showMessageDialog(getJFrame(),
							"Character has already performed training.\n" +
							"Next training starts at " +
							TimeManagement.getTM().getNextTrainingTime(),
							"Training already performed", 
							JOptionPane.DEFAULT_OPTION);
				}
			}
			
		}
		else if(e.getEventType().equals(EventType.ENTERED))
		{
			if(i >= Player.firstAttribID)
			{
				Point p = MouseInfo.getPointerInfo().getLocation();
				p.translate(50, 0);
				getTrainToolTip().setLocation(p);
				getTrainToolTip().setVisible(true);
			}
		}
		else if(e.getEventType().equals(EventType.EXITED))
		{
			if(i >= Player.firstAttribID)
			{
				getTrainToolTip().setVisible(false);
			}
		}
	}

}
